package com.emin.platform.productCenter.multidatasource;

import com.emin.platform.productCenter.util.PltThreadLocalUtil;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.orm.hibernate5.LocalSessionFactoryBuilder;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;


/**
 * 此类用于创建SessionFactory
 *
 * @author Jack
 * @version V1.0
 * @Description: 此类用于创建SessionFactory，创建好的SessionFactory保存在sessionFactories中
 * @date 2017/10/24 14:42
 */
@Component("sessionFactory")
@Order(2)
public class MultiSessionFactoryBean extends LocalSessionFactoryBean {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private String entityCfgUrl;
    // 这个暂时还没用到，用于拦截sql
    private Interceptor entityInterceptor;

    public MultiSessionFactoryBean() {
    }

    public void setEntityCfgUrl(String entityCfgUrl) {
        this.entityCfgUrl = entityCfgUrl;
    }

    public String getEntityCfgUrl() {
        return this.entityCfgUrl;
    }

    public Interceptor getEntityInterceptor() {
        return this.entityInterceptor;
    }

    public void setEntityInterceptor(Interceptor entityInterceptor) {
        this.entityInterceptor = entityInterceptor;
    }

    /**
     * 创建多个SessionFactory
     *
     * @return SessionFactory
     * @throws
     * @author Jack
     * @date 2017/10/24
     */
    protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder sfb) {
        Set<Entry<Long, DataSource>> dsEntrySet = MultiDataSource.getInstance().getDataSourceSet();
        Iterator var3 = dsEntrySet.iterator();
        while (var3.hasNext()) {
            Entry<Long, DataSource> entry = (Entry) var3.next();
            Long dataSourceKey = (Long) entry.getKey();
            DataSource ds = (DataSource) entry.getValue();
            this.setDataSource(ds);
            if (this.entityInterceptor != null) {
                super.setEntityInterceptor(this.entityInterceptor);
            }
            this.setConfigLocation((new PathMatchingResourcePatternResolver()).getResource(this
                    .entityCfgUrl));
            SessionFactory sessionFactory = super.buildSessionFactory(sfb);
            this.putSessionFactory(dataSourceKey, sessionFactory);
        }
        return MultiSessionFactory.getInstance();
    }

    /**
     * 创建单个SessionFactory
     *
     * @return SessionFactory
     * @throws
     * @author Jack
     * @date 2017/10/24
     */
    public SessionFactory bulidSessionFactoryByDataSourceKey() throws Exception {
        Long companyId = this.getCompanyId();
        DataSource ds = MultiDataSource.getInstance().getDataSource();
        if (ds != null) {
            this.setDataSource(ds);
            this.setConfigLocation((new PathMatchingResourcePatternResolver()).getResource(this
                    .entityCfgUrl));
            // 这个暂时还没用到，用于拦截sql
            if (this.entityInterceptor != null) {
                super.setEntityInterceptor(this.entityInterceptor);
            }
            LocalSessionFactoryBuilder sfb = new LocalSessionFactoryBuilder(ds, this
                    .getResourceLoader(), this.getMetadataSources());
            SessionFactory sessionFactory = super.buildSessionFactory(sfb);
            this.putSessionFactory(companyId, sessionFactory);
            return sessionFactory;
        } else {
            this.logger.error("Please check whether the company is valid or not!!!!!!!!!!");
            return null;
        }
    }


    private void putSessionFactory(Long key, SessionFactory sessionFactory) {
        MultiSessionFactory.getInstance().putSessionFactory(key, sessionFactory);
    }

    public void destroy() throws HibernateException {
        Set<Long> keys = MultiSessionFactory.getInstance().getSessionFactoryKeys();
        Iterator var2 = keys.iterator();
        while (var2.hasNext()) {
            Long key = (Long) var2.next();
            SessionFactory sessionFactory = MultiSessionFactory.getInstance().getSessionFactory
                    (key);
            sessionFactory.close();
            MultiDataSource.getInstance().removeDataSource(key);
        }
    }

    private Long getCompanyId() {
        return PltThreadLocalUtil.getCompanyId();
    }
}
